package com.youhome.business.controller;

import com.youhome.business.dto.DTOCompany;
import com.youhome.common.exception.CustomException;
import com.youhome.service.model.BCompany;
import com.youhome.service.model.BUser;
import com.youhome.service.model.Principal;
import com.youhome.common.response.Result;
import com.youhome.common.response.ResultCode;
import com.youhome.service.service.*;
import com.youhome.utils.ValidationUtils;
import io.swagger.annotations.*;
import org.modelmapper.ModelMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
import org.springframework.security.web.authentication.rememberme.PersistentTokenBasedRememberMeServices;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;

/**
 * Created by chen365 on 2017/10/18.
 */
@RestController
@Api(tags = "注册，登陆，注销")
public class HomeController {
    private static final BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();

    @Autowired
    private AuthenticationService authenticationService;

    @Autowired
    private LoginPersistenceService loginPersistenceService;

    @Autowired
    private BCompanyService bCompanyService;

    @Autowired
    private JSMSValidateService jsmsValidateService;

    @Autowired
    private BUserService bUserService;

    /**
     * 登陆
     *
     * @param request
     * @param response
     * @param phone
     * @param code
     * @param msgid
     * @return
     */

    @ApiOperation(value = "登陆", notes = "根据 phone（手机）和 password (密码)登陆", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ApiImplicitParams({
            @ApiImplicitParam(dataType = "String", name = "phone", value = "手机", required = true, paramType = "query"),
            @ApiImplicitParam(dataType = "String", name = "code", value = "短信", required = true, paramType = "query"),
            @ApiImplicitParam(dataType = "String", name = "msgid", value = "短信ID", required = true, paramType = "query")
    })
    @PostMapping(value = "/login")
    public Object login(HttpServletRequest request, HttpServletResponse response,
                        @RequestParam("phone") String phone,
                        @RequestParam("code") String code,
                        @RequestParam("msgid") String msgid) {


        if (!ValidationUtils.isPhone(phone)) {
            return new Result(ResultCode.ERROR_PHONE);
        }

//        if (StringUtils.isEmpty(code)) {
//            return new Result(ResultCode.EMPTY_SMS_VALIDATE_CODE);
//        }
//
//        if (StringUtils.isEmpty(msgid)) {
//            return new Result(ResultCode.EMPTY_MSGID);
//        }


        BUser bUser = bUserService.selectByPhone(phone);
        if (bUser == null) {
            return new Result(ResultCode.NOT_EXIST_USER);
        }

        UserDetails userDetails = authenticationService.loadUserByPhone(phone);


//        if (!passwordEncoder.matches(password, userDetails.getPassword())) {
//            return new Result(ResultCode.FAIL_LOGIN);
//        }

/*
        try {
            JSMSClient jsmsClient = new JSMSClient(smsConfig.getSecret(), smsConfig.getAppkey());
            ValidSMSResult result = jsmsClient.sendValidSMSCode(msgid, code);
            if (!result.getIsValid()) {
                return new Result(ResultCode.ERROR_VALIDATE_CODE);
            }
        } catch (APIConnectionException e) {
            return new Result(ResultCode.VALIDATE_CODE_FAILED);
        } catch (APIRequestException e) {
            return new Result(ResultCode.VALIDATE_CODE_FAILED);
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(ResultCode.ERROR);
        }

        */

        Authentication auth = new UsernamePasswordAuthenticationToken(userDetails, code, userDetails.getAuthorities());
        SecurityContextHolder.getContext().setAuthentication(auth);

        HttpServletRequestWrapper wrapper = new HttpServletRequestWrapper(request) {
            @Override
            public String getParameter(String name) {
                return "true";
            }
        };

        PersistentTokenBasedRememberMeServices tokenService =
                new PersistentTokenBasedRememberMeServices(code, authenticationService, loginPersistenceService);
        tokenService.loginSuccess(wrapper, response, auth);

        Principal principal = (Principal) userDetails;
        BUser user = principal.getUser();

        return new Result(ResultCode.SUCCESS, user);
    }

    /**
     * 退出登陆
     *
     * @param request
     * @param response
     * @return
     */
    @ApiOperation(value = "退出登陆", notes = "退出登陆", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @GetMapping(value = "/exit")
    public Object logout(HttpServletRequest request, HttpServletResponse response) {
        bUserService.logout(request, response);
        return new Result(ResultCode.SUCCESS);
    }


    /**
     * 注册
     */
    @ApiOperation(value = "注册", notes = "企业用户注册", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ApiImplicitParams({
            @ApiImplicitParam(dataType = "String", name = "phone", value = "手机", required = true, paramType = "query"),
            @ApiImplicitParam(dataType = "String", name = "code", value = "验证码", required = true, paramType = "query"),
            @ApiImplicitParam(dataType = "String", name = "msgid", value = "短信ID", required = true, paramType = "query"),
            @ApiImplicitParam(dataType = "String", name = "name", value = "公司名称", example = "华美优胜", required = true, paramType = "query"),
            @ApiImplicitParam(dataType = "String", name = "province", value = "公司所在省", example = "广东省", required = true, paramType = "query"),
            @ApiImplicitParam(dataType = "String", name = "city", value = "公司所在市", example = "深圳市", required = true, paramType = "query"),
            @ApiImplicitParam(dataType = "String", name = "area", value = "公司所在区", example = "南山区", required = true, paramType = "query"),
            @ApiImplicitParam(dataType = "String", name = "address", value = "公司所在地址", example = "沙河中航工业区", required = true, paramType = "query"),
            @ApiImplicitParam(dataType = "String", name = "logo", value = "公司Logo(base64)", example = "...", required = false, paramType = "query"),
            @ApiImplicitParam(dataType = "String", name = "officialAccounts", value = "公司公众号", required = false, paramType = "query"),
            @ApiImplicitParam(dataType = "String", name = "officialAccountsQRCode", value = "公司公众号二维码", required = false, paramType = "query"),
            @ApiImplicitParam(dataType = "String", name = "serviceNumber", value = "公司服务号", required = false, paramType = "query"),
            @ApiImplicitParam(dataType = "String", name = "website", value = "公司网站", example = "www.mf-data.com", required = false, paramType = "query"),
            @ApiImplicitParam(dataType = "String", name = "scale", value = "公司规模", example = "1000人以上", required = false, paramType = "query"),
            @ApiImplicitParam(dataType = "String", name = "principalEmail", value = "负责人邮箱", example = "zhangshan@163.com", required = true, paramType = "query"),
            @ApiImplicitParam(dataType = "String", name = "principalName", value = "负责人姓名", example = "张三", required = true, paramType = "query"),
            @ApiImplicitParam(dataType = "String", name = "principalPhone", value = "负责人手机", example = "18988889999", required = true, paramType = "query"),
            @ApiImplicitParam(dataType = "int", name = "credentialType", value = "证件类型，1普通营业执照，2多证合一营业执照", required = true, paramType = "query"),
            @ApiImplicitParam(dataType = "String", name = "businessLicenseNumber", value = "营业执照证件号", required = false, paramType = "query"),
            @ApiImplicitParam(dataType = "String", name = "organizationCode", value = "组织机构代码", required = false, paramType = "query"),
            @ApiImplicitParam(dataType = "String", name = "creditCode", value = "统一社会信用代码", required = false, paramType = "query"),
            @ApiImplicitParam(dataType = "String", name = "photo", value = "五证合一图片(base64)", example = "...", required = false, paramType = "query"),
            @ApiImplicitParam(dataType = "String", name = "companyTel", value = "公司电话", required = false, paramType = "query"),
            @ApiImplicitParam(dataType = "String", name = "companyEmail", value = "公司邮箱", required = false, paramType = "query")
    })
    @PostMapping(value = "/register")
    public Object register(String phone, String code, String msgid,
                           String name, String province, String city, String area, String address, String logo, String officialAccounts, String officialAccountsQRCode,
                           String serviceNumber, String website, String scale, String principalEmail, String principalName,
                           String principalPhone, Integer credentialType, String businessLicenseNumber, String organizationCode,
                           String creditCode, String photo, String companyTel, String companyEmail) {

        BCompany company = new BCompany();

        company.setName(name);
        company.setProvince(province);
        company.setCity(city);
        company.setArea(area);
        company.setAddress(address);
        company.setLogo(logo);
        company.setOfficialAccounts(officialAccounts);
        company.setOfficialAccountsQRCode(officialAccountsQRCode);
        company.setServiceNumber(serviceNumber);
        company.setWebsite(website);
        company.setScale(scale);
        company.setPrincipalEmail(principalEmail);
        company.setPrincipalName(principalName);
        company.setPrincipalPhone(principalPhone);
        company.setCredentialType(credentialType);
        company.setBusinessLicenseNumber(businessLicenseNumber);
        company.setOrganizationCode(organizationCode);
        company.setCreditCode(creditCode);
        company.setPhoto(photo);
        company.setCompanyTel(companyTel);
        company.setCompanyEmail(companyEmail);

        if (!ValidationUtils.isPhone(phone)) {
            return new Result(ResultCode.ERROR_PHONE);
        }
        if (StringUtils.isEmpty(code)) {
            return new Result(ResultCode.EMPTY_SMS_VALIDATE_CODE);
        }
//        if (StringUtils.isEmpty(msgid)) {
//            return new Result(ResultCode.EMPTY_MSGID);
//        }

        if (bUserService.isExistByPhone(phone)) {
            return new Result(ResultCode.REGISTERED_PHONE);
        }

        //证件类型： 1普通营业执照，2多证合一营业执照
        if (StringUtils.isEmpty(credentialType)) {
            return new Result(ResultCode.EMPTY_CREDENTIAL_TYPE);
        }
        if (credentialType == 1) {
            //营业执照证件号
            if (StringUtils.isEmpty(businessLicenseNumber)) {
                return new Result(ResultCode.EMPTY_BUSINESS_LICENSE_NUMBER);
            }
            //组织机构代码
            if (StringUtils.isEmpty(organizationCode)) {
                return new Result(ResultCode.EMPTY_ORGANIZATION_CODE);
            }
        } else if (credentialType == 2) {
            //统一社会信用代码
            if (StringUtils.isEmpty(creditCode)) {
                return new Result(ResultCode.EMPTY_CREDIT_CODE);
            }
        } else {
            return new Result(ResultCode.ERROR_CREDENTIAL_TYPE);
        }

        //公司所在地址
        if (StringUtils.isEmpty(address)) {
            return new Result(ResultCode.EMPTY_COMPANY_ADDRESS);
        }
        //负责人邮箱
        if (!ValidationUtils.isEmail(principalEmail)) {
            return new Result(ResultCode.ERROR_PRINCIPAL_EMAIL);
        }
        //负责人姓名
        if (StringUtils.isEmpty(principalName)) {
            return new Result(ResultCode.EMPTY_PRINCIPAL_NAME);
        }
        //负责人手机
        if (!ValidationUtils.isPhone(principalPhone)) {
            return new Result(ResultCode.ERROR_PHONE);
        }

        //try {

        if (bCompanyService.register(phone, company) == 1) {
            return new Result(ResultCode.SUCCESS);
        }

//            JSMSClient jsmsClient = new JSMSClient(smsConfig.getSecret(), smsConfig.getAppkey());
//            ValidSMSResult result = jsmsClient.sendValidSMSCode(msgid, code);
//            if (result.getIsValid()) {
//                if (bCompanyService.register(phone, company, businessInfo) == 1) {
//                    return new Result(ResultCode.SUCCESS);
//                }
//            } else {
//                return new Result(ResultCode.ERROR_VALIDATE_CODE);
//            }
//        } catch (APIConnectionException e) {
//            return new Result(ResultCode.VALIDATE_CODE_FAILED);
//        } catch (APIRequestException e) {
//            Integer ErrorCode = e.getErrorCode();
//            if (ErrorCode == 50010) {
//                return new Result(ResultCode.CAPTCHA_CODE);
//            }
//            if (ErrorCode == 50011) {
//                return new Result(ResultCode.VERIFICATION_CODE_EXPIRATION);
//            }
//            if (ErrorCode == 50012) {
//                return new Result(ResultCode.VERIFICATION_CODE_HAS_BEEN_VALIDATED);
//            }
//            if (ErrorCode == 50014) {
//                return new Result(ResultCode.CAN_SEND_SHORT_MESSAGE_MARGIN_SHORT);
//            }
//            if (ErrorCode == 50015) {
//                return new Result(ResultCode.VERIFY_CODE_IS_EMPTY);
//            }
//            if (ErrorCode == 50034) {
//                return new Result(ResultCode.SEND_REPEATEDLY);
//            }
//        } catch (Exception e) {
//            e.printStackTrace();
//            return new Result(ResultCode.ERROR);
//        }
        return new Result(ResultCode.FAIL);
    }


    @ApiOperation(value = "企业用户注册", notes = "企业用户注册", response = Result.class, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @PostMapping(value = "/company")
    public Object register(@ApiParam @Validated DTOCompany company) throws CustomException {
        //判断手机是否已经被注册
        if (bUserService.isExistByPhone(company.getPhone())) {
            //return new Result(ResultCode.REGISTERED_PHONE);
            throw new CustomException(ResultCode.REGISTERED_PHONE);
        }
        if (company.getCredentialType().equals(1)) {
            //营业执照证件号
            if (StringUtils.isEmpty(company.getBusinessLicenseNumber())) {
                //return new Result(ResultCode.EMPTY_BUSINESS_LICENSE_NUMBER);
                throw new CustomException(ResultCode.EMPTY_BUSINESS_LICENSE_NUMBER);
            }
            //组织机构代码
            if (StringUtils.isEmpty(company.getOrganizationCode())) {
                //return new Result(ResultCode.EMPTY_ORGANIZATION_CODE);
                throw new CustomException(ResultCode.EMPTY_ORGANIZATION_CODE);
            }
        } else if (company.getCredentialType().equals(2)) {
            //统一社会信用代码
            if (StringUtils.isEmpty(company.getCreditCode())) {
                //return new Result(ResultCode.EMPTY_CREDIT_CODE);
                throw new CustomException(ResultCode.EMPTY_CREDIT_CODE);
            }
        } else {
            //return new Result(ResultCode.ERROR_CREDENTIAL_TYPE);
            throw new CustomException(ResultCode.ERROR_CREDENTIAL_TYPE);
        }
        //短信验证
        //boolean validate_status = jsmsValidateService.validate(company.getPhone(), company.getSmsId(), company.getSmsCode());
        boolean validate_status = true;
        if (validate_status) {
            ModelMapper modelMapper = new ModelMapper();
            BCompany bCompany = modelMapper.map(company, BCompany.class);
            if (bCompanyService.register(company.getPhone(), bCompany) > 0) {
                return new Result(ResultCode.SUCCESS);
            }
        }
        return new Result(ResultCode.FAIL);
    }

}
